//
//  NavigationController.swift
//  FrameProduct
//
//  Created by delegate on 2024/2/4.
//

import UIKit

class NavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        navi()
    }
    func navi() {
        let bgColor = UIColor.lxs.hex("#061637")
        let naviTextColor = UIColor.lxs.hex("#FFFFFF")
        
        view.backgroundColor = bgColor
        
        self.navigationBar.shadowImage = UIImage()
        self.navigationBar.layer.shadowColor = bgColor.cgColor
        self.navigationBar.layer.shadowRadius = 20
        self.navigationBar.layer.shadowOpacity = 0.2
        self.navigationBar.layer.shadowOffset = CGSize(width: 0, height: 5)
        self.navigationBar.tintColor = naviTextColor
        self.navigationBar.isTranslucent = false
        self.navigationBar.barTintColor = bgColor

        let appearance = UINavigationBar.appearance()
        appearance.shadowImage = UIImage()
        appearance.layer.shadowColor = bgColor.cgColor
        appearance.layer.shadowRadius = 20
        appearance.layer.shadowOpacity = 0.2
        appearance.layer.shadowOffset = CGSize(width: 0, height: 5)
        appearance.tintColor = naviTextColor //前景色，按钮颜色
        appearance.isTranslucent = false // 导航条背景是否透明
        appearance.barTintColor = bgColor //背景色，导航条背景色
        appearance.titleTextAttributes = [
            NSAttributedString.Key.foregroundColor: naviTextColor,
            NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20, weight: .medium)
        ] // 设置导航条标题颜色，还可以设置其它文字属性，只需要在里面添加对应的属性
        
        // 解决iOS15 barTintColor设置无效的问题，参考https://developer.apple.com/forums/thread/682420
        if #available(iOS 15.0, *) {
            let newAppearance = UINavigationBarAppearance()
            newAppearance.configureWithOpaqueBackground()
            newAppearance.backgroundColor = bgColor
            newAppearance.shadowImage = UIImage()
            newAppearance.shadowColor = bgColor
            newAppearance.titleTextAttributes = [
                NSAttributedString.Key.foregroundColor: naviTextColor,
                NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20, weight: .medium)
            ]
            appearance.standardAppearance = newAppearance
            appearance.scrollEdgeAppearance = appearance.standardAppearance
        }
    }
    
    // MARK: - Properties
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        return super.preferredStatusBarStyle
    }
    
    open override var childForStatusBarStyle: UIViewController?{
        return topViewController
    }
    open override var childForStatusBarHidden: UIViewController?{
        return topViewController
    }
    
    open override func setViewControllers(_ viewControllers: [UIViewController], animated: Bool) {
        
        // 当前控制器执行push的时候，禁止手势右划返回，避免出现crash的现象
        if self.responds(to: #selector(getter: interactivePopGestureRecognizer)) == true {
            self.interactivePopGestureRecognizer?.isEnabled = false
        }
        
        if viewControllers.count > 0 {
            let viewController = viewControllers.last!
            viewController.hidesBottomBarWhenPushed = true
            if viewController.navigationItem.leftBarButtonItem == nil  {
                viewController.configLeftBarButtonItem(with: R.image.navi_back(), offset: 1) { [weak viewController] in
                    viewController?.gobackByPop()
                }
            }
        }
        
        super.setViewControllers(viewControllers, animated: animated)
        // 处理了push后隐藏底部UITabBar的情况，并解决了iPhonX上push时UITabBar上移的问题。
        if var rect = self.tabBarController?.tabBar.frame {
            rect.origin.y = UIScreen.main.bounds.size.height - rect.size.height
            self.tabBarController?.tabBar.frame = rect
        }
    }
    
    open override func pushViewController(_ viewController: UIViewController, animated: Bool) {
         
         // 当前控制器执行push的时候，禁止手势右划返回，避免出现crash的现象
         if self.responds(to: #selector(getter: interactivePopGestureRecognizer)) == true {
             self.interactivePopGestureRecognizer?.isEnabled = false
         }

         if children.count > 0 {
             viewController.hidesBottomBarWhenPushed = true
             if viewController.navigationItem.leftBarButtonItem == nil  {
                 viewController.configLeftBarButtonItem(with: R.image.navi_back(), offset: 1) { [weak viewController] in
                     viewController?.gobackByPop()
                 }
             }
         }
         super.pushViewController(viewController, animated: animated)
         // 处理了push后隐藏底部UITabBar的情况，并解决了iPhonX上push时UITabBar上移的问题。
         if var rect = self.tabBarController?.tabBar.frame {
             rect.origin.y = UIScreen.main.bounds.size.height - rect.size.height
             self.tabBarController?.tabBar.frame = rect
         }
     }
    
    // MARK: - UINavigationControllerDelegate
    open func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        // 当前控制器执行push的时候，禁止手势右划返回，避免出现crash的现象
        if self.responds(to: #selector(getter: interactivePopGestureRecognizer)) == true {
            self.interactivePopGestureRecognizer?.isEnabled = self.viewControllers.count > 1
        }
    }
}

extension UIViewController {
    
    @objc open func gobackByPop() {
        self.navigationController?.popViewController(animated: true)
    }
    
    private func createLeftBarButtonItem(with image: UIImage?, offset: CGFloat = 1.0, tapClosure: (() -> Void)?) -> UIBarButtonItem {
        // 返回按钮左侧的偏移量
        let offset: CGFloat = 1
        let wh: CGFloat = 44.0
        
        let backNavBtn = NavigationItemButton(frame: .zero)
        backNavBtn.contentHorizontalAlignment = .left
        
        backNavBtn.setImage(image, for: .normal)
        backNavBtn.setImage(image, for: .highlighted)
        backNavBtn.clickEdgeInsets = UIEdgeInsets(top: 0, left: offset, bottom: 0, right: 10)
        backNavBtn.tapClosure = tapClosure
        backNavBtn.tintColor = .white
        backNavBtn.alignmentRectInsetsOverride = UIEdgeInsets(top: 0, left: offset, bottom: 0, right: -offset)
        backNavBtn.translatesAutoresizingMaskIntoConstraints = false
        backNavBtn.widthAnchor.constraint(equalToConstant: wh).isActive = true
        backNavBtn.heightAnchor.constraint(equalToConstant: wh).isActive = true

        
        let backItem = UIBarButtonItem(customView: backNavBtn)
        return backItem
    }
    
    public func configLeftBarButtonItem(with image: UIImage?, offset: CGFloat = 1.0, tapClosure: (() -> Void)? = nil) {
        let backItem = createLeftBarButtonItem(with: image, offset: offset) { [weak self] in
            if tapClosure != nil {
                tapClosure?()
            } else {
                self?.gobackByPop()
            }
        }
        let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
        spacer.width = -offset
        navigationItem.leftBarButtonItem = backItem//[spacer, backItem]
    }
}

private class NavigationItemButton: UIButton {
    var alignmentRectInsetsOverride: UIEdgeInsets = .zero
    var tapClosure: (() -> Void)?
    
    override var alignmentRectInsets: UIEdgeInsets {
        if alignmentRectInsetsOverride == .zero {
            return .zero
        }
        else {
            return self.alignmentRectInsetsOverride
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    func commonInit() {
        addTarget(self, action: #selector(clickSelf), for: .touchUpInside)
    }
    
    @objc func clickSelf() {
        tapClosure?()
    }
}
